#ifndef SWFEncoder_h__
#define SWFEncoder_h__

#include "TagHandler.h"
#include "SWFStructs.h"
#include <map>

class SWFOutputStream;

class SWFEncodeContext
{
public:
	SWFTag* currentTag;
	SWFOutputStream* tagStream;
	
	int defineShapeCode;
private:
	std::map<SWFTag*, UI16> _characterIdMap;
	UI16 _characterIdCount;
public:
	SWFEncodeContext()
		: currentTag(nullptr)
		, tagStream(nullptr)
		, defineShapeCode(0)
		, _characterIdCount(1)
	{

	}
	UI16 getCharacterId(SWFTag* tag);
	UI16 getCharacterId(SWFTagRef* r);
};

class SWFEncoder
	: public TagHandler
{
private:
	SWFOutputStream* _stream;
	SWFOutputStream* _tagStream;
	SWFEncodeContext* _context;
	SWF* _swf;
	std::string _filePath;
	std::vector<SWFTag*> _doneList;
private:
	void writeTag(SWFTag* tag, SWFOutputStream* stream);
	void encodeTag(SWFTag*);
	void defineTag(SWFTag* tag);

	void encodeShapeWithStyle(UI8 tagCode, ShapeWithStyle* shape);
	UI16 getCharacterId(SWFTag* tag);
	UI16 getCharacterId(SWFTagRef* tagRef);
public:
	SWFEncoder();
	~SWFEncoder();

	int save(SWF* swf, const std::string& filePath);

	virtual void unknow( TagUnknow* tag );

	virtual void doABC( TagDoABC* tag );

	virtual void metadata( TagMetadata* tag );

	virtual void frameLabel( TagFrameLabel* tag );

	virtual void setBackgroundColor( TagSetBackgroundColor* tag );

	virtual void fileAttributes( TagFileAttributes* tag );

	virtual void end( TagEnd* tag );

	virtual void scriptLimits( TagScriptLimits* tag );

	virtual void symbolClass( TagSymbolClass* tag );

	virtual void importAssets2( TagImportAssets2* tag );

	virtual void protect( TagProtect* tag );

	virtual void exportAssets( TagExportAssets* tag );

	virtual void enableDebugger( TagEnableDebugger* tag );

	virtual void enableDebugger2( TagEnableDebugger2* tag );

	virtual void setTabIndex( TagSetTabIndex* tag );

	virtual void defineScalingGrid( TagDefineScalingGrid* tag );

	virtual void defineSceneAndFrameLabelData( TagDefineSceneAndFrameLabelData* tag );

	virtual void defineShape( TagDefineShape* tag );

	virtual void defineShape2( TagDefineShape2* tag );

	virtual void defineShape3( TagDefineShape3* tag );

	virtual void defineShape4( TagDefineShape4* tag );

	virtual void defineButton( TagDefineButton* tag );

	virtual void defineButton2( TagDefineButton2* tag );

	virtual void defineButtonCxform( TagDefineButtonCxform* tag );

	virtual void defineButtonSound( TagDefineButtonSound* tag );

	virtual void defineSprite( TagDefineSprite* tag );

	virtual void defineMorphShape( TagDefineMorphShape* tag );

	virtual void defineMorphShape2( TagDefineMorphShape2* tag );

	virtual void defineFont( TagDefineFont* tag );

	virtual void defineFont2( TagDefineFont2* tag );

	virtual void defineFont3( TagDefineFont3* tag );

	virtual void defineFont4( TagDefineFont4* tag );

	virtual void defineFontInfo( TagDefineFontInfo* tag );

	virtual void defineFontInfo2( TagDefineFontInfo2* tag );

	virtual void defineFontAlignZones( TagDefineFontAlignZones* tag );

	virtual void defineFontName( TagDefineFontName* tag );

	virtual void defineText( TagDefineText* tag );

	virtual void defineText2( TagDefineText2* tag );

	virtual void defineEditText( TagDefineEditText* tag );

	virtual void cSMTextSettings( TagCSMTextSettings* tag );

	virtual void showFrame( TagShowFrame* tag );

	virtual void placeObject( TagPlaceObject* tag );

	virtual void placeObject2( TagPlaceObject2* tag );

	virtual void placeObject3( TagPlaceObject3* tag );

	virtual void defineBitsJPEG2( TagDefineBitsJPEG2* tag );

	virtual void defineBitsJPEG3( TagDefineBitsJPEG3* tag );

	virtual void defineBinaryData( TagDefineBinaryData* tag );

	virtual void productInfo( TagProductInfo* tag );

	virtual void removeObject(TagRemoveObject* tag);

	virtual void removeObject2(TagRemoveObject2* tag);

	virtual void defineBitsLossless( TagDefineBitsLossless* tag );

	virtual void defineBitsLossless2( TagDefineBitsLossless2* tag );

	virtual void defineSound( TagDefineSound* tag );

};
#endif // SWFEncoder_h__
